#include<iostream>
#include<thread>
#include<list>
#include<vector>
#include<mutex>

using namespace std;

once_flag g_flag;
call_once(g_flag, G()); //两个线程同时执行到这里，其中一个要等另一个执行完G()函数

class MyCAS
{
    private:
    MyCAS() {}

    private:
    static MyCAS *m_instance;

    public:
    static MyCAS *GetInstance(){
        //加锁可以解决问题，但是，加锁只是为了解决开始初始化的问题，不用初始化的时候，锁就没有意义，这样就会导致代码效率低
        //解决办法：
        //使用双重判断，提高代码效率
        if(m_instance==NULL){
            m_instance = new MyCAS();
            static CGarhuishou c1;  //静态对象 在程序退出之后，必然会被析构。其析构的时候，会析构MyCAS
        }
        return m_instance;
    }

    class CGarhuishou
    {
        public:
        ~CGarhuishou()
        {
            if(MyCAS::m_instance)
            {
                delete MyCAS::m_instance;
                MyCAS::m_instance = NULL;
            }
        }
    };

    void func(){
        cout<<"测试"<<endl;
    }
}

MyCAS *MyCAS::m_instance = NULL;

void mythread(){
    cout<<"xianch"<<endl;
    MyCAS *p_a = MyCAS::GetInstance();  //两个线程可能先后创建实例
    cout<<"jieshu"<<endl;
}

int main(){
    MyCAS* p_a  = MyCAS::GetInstance();
    MyCAS* p_b = MyCAS::GetInstance();

    //需要在我们自己创建的线程中创建MyCAS这个单例类的对象，这中线程可能不止(最少2个)
    //我们可能会面临GetInstance()这种成员函数要互斥

    //四call_once()
    //功能是能够保证函数a()只被调用一次
    //具备互斥量这种能力，而且效率上，比互斥量消耗的资源更少
    //需要与一个标记综合使用，这个标记once_flag；其实once_flag是一个结构


    thread myobj1(mythread);
    thread myobj2(mythread);
    myobj1.join();
    myobj2.join();

    cout<<"i love china"<<endl; 

    return 0;
}
